import pickle
from pathlib import Path
from faker import Faker

faker_ins = Faker()


class FileCache(object):
    def __init__(self, filename='_temp_', init_value=None, after_func=None):
        if init_value is None:
            init_value = {}

        if isinstance(filename, str) and filename.find('.pkl') == -1:
            filename += '.pkl'

        file = filename if isinstance(filename, Path) else Path(filename)
        file.parent.mkdir(exist_ok=True, parents=True)

        if file.exists():
            self.data = pickle.load(file.open('rb'))
        else:
            self.data = init_value

        self.file = file
        self.after_func = after_func or str

    def __enter__(self):
        return self

    def __exit__(self, *args):
        self.__save()

    def __save(self):
        pickle.dump(self.data, self.file.open('wb'))

    def __getattr__(self, item):
        if hasattr(self.data, item):
            return getattr(self.data, item)
        elif item in self.data.keys():
            return self.data[item]

    def __getitem__(self, key):
        return self.data[key]

    def __setitem__(self, key, value):
        self.data[key] = value

    def __delitem__(self, key):
        del self.data[key]

    def __contains__(self, key):
        return key in self.data

    def __bool__(self):
        return bool(self.data)

    def __eq__(self, other):
        return other == self.data

    def __del__(self):
        self.after_func()
        self.__save()


def get_value(source, path: str, dft=None):
    dst = source
    for key in path.strip('.').split('.'):
        if key.startswith('0') and key.isdigit():
            key = int(key)
            try:
                dst = dst[key]
            except IndexError:
                raise IndexError(f"{key} 超出索引范围")
        elif getattr(dst, key, None):
            dst = getattr(dst, key)
        elif isinstance(dst, dict):
            dst = dst.get(key, dft)
        else:
            return dft

    return dst


def random_ua():
    """随机的 user-agent"""
    return faker_ins.user_agent()
